package com.dstz.form.generator;

import org.jsoup.nodes.Element;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dstz.base.api.exception.BusinessException;
import com.dstz.base.core.util.StringUtil;
import com.dstz.base.core.util.ThreadMapUtil;
import com.dstz.bus.api.constant.BusTableRelType;
import com.dstz.bus.api.model.IBusTableRel;
import com.dstz.bus.api.model.IBusinessColumn;
import com.dstz.form.model.design.FormColumn;
import com.dstz.form.model.design.FormGroup;

/**
 * <pre>
 * 描述：vue pc端的表单生成器
 * 作者:aschs
 * 邮箱:aschs@qq.com
 * 日期:2018年12月19日
 * 版权:summer
 * </pre>
 */
@Component
public class VueFormElementGenerator extends AbsFormElementGenerator {

	private void handleVModel(Element element, IBusinessColumn column) {
		//添加上  placeholder 的支持
		handleElementPlaceHolder(column, element);
				
		String boCode = (String) ThreadMapUtil.get("boCode");
		IBusTableRel relation = (IBusTableRel) ThreadMapUtil.get("relation");
		// 如果是多行子表
		if (relation.getType().equals(BusTableRelType.ONE_TO_MANY.getKey())) {
			element.attr("v-model", column.getTable().getKey() + "." + column.getKey());
			return;
		}

		element.attr("v-model", getScopePath(relation) + "." + column.getKey());
		
	}

	@Override
	protected String getColumnOnetext(IBusinessColumn column) {

		Element element = getElement("input").attr("type", "text").addClass("form-control");

		handleVModel(element, column);
		handlePermission(element, column);
		handleValidateRules(element, column);

		return element.toString();
	}

	/**
	 * <ab-date class=" form-control" v-model="data.bdkj.rqkj" desc="日期控件" ab-validate="{}" v-ab-permission="permission.bdkj.bdkj.rqkj" format="yyyy-MM-dd"></ab-date>
	 */
	@Override
	protected String getColumnDate(IBusinessColumn column) {
		Element element = getElement("ab-date").attr("type", "text").addClass("form-control");

		handleVModel(element, column);
		handlePermission(element, column);
		handleValidateRules(element, column);

		String configStr = column.getCtrl().getConfig();
		if (StringUtil.isEmpty(configStr)) {
			throw new BusinessException(String.format("表【%s】日期字段  【%s】解析失败,配置信息不能为空", column.getTable().getKey(), column.getComment()));
		}

		String format = JSON.parseObject(configStr).getString("format");
		// yyyy-MM-dd HH:mm:ss pc 移动端为：YYYY-MM-DD HH:mm
		element.attr("format", format);
		
		return element.toString();
	}

	@Override
	protected String getColumnDic(IBusinessColumn column) {
		Element element = getElement("ab-dict").attr("type", "text").addClass("input-div");

		handleVModel(element, column);
		handlePermission(element, column);
		handleValidateRules(element, column);

		JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
		if (!config.containsKey("key")) {
			throw new BusinessException(String.format("表【%s】数据字典  字段【%s】解析失败,alias 配置信息不能为空", column.getTable().getKey(), column.getComment()));
		}

		element.attr("dict-key", config.getString("key"));

		return element.toString();
	}

	/**
	 * <pre>
	 * ab-serial-no
	 * </pre>
	 */
	@Override
	protected String getColumnIdentity(IBusinessColumn column) {
		Element element = getElement("ab-serial-no").attr("type", "text").addClass("form-control");
		handleVModel(element, column);
		element.attr("v-bind:ab-permission", getPermissionPath(column));
		handleValidateRules(element, column);

		JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
		if (!config.containsKey("alias")) {
			throw new BusinessException(String.format("表【%s】流水号  字段【%s】解析失败,alias 配置信息不能为空", column.getTable().getKey(), column.getComment()));
		}
		element.attr("serial-no", config.getString("alias"));
		
		return element.toString();
	}

	@Override
	protected String getColumnMultitext(IBusinessColumn column) {
		Element element = getElement("textarea").attr("type", "text").addClass("form-control");

		handleVModel(element, column);
		handlePermission(element, column);
		handleValidateRules(element, column);

		return element.toString();
	}

	/**
	 * <pre>
	 * <ab-checkbox v-model="data.kjcs.ah" v-ab-permission="permission.kjcs.cskj.ah" v-ab-validate="{}" desc="爱好">
	 *       <div slot-scope="scope">
	 *          <label class=" checkbox-inline"><input type="checkbox" name="testttt" v-model="scope.tempData.currentValue" value="y"/>羽毛器</label>
	 *          <label class=" checkbox-inline"><input name="testttt" type="checkbox" v-model="scope.tempData.currentValue" value="l"/>篮球</label>
	 *       	<label class=" checkbox-inline"><input type="checkbox" name="testttt" v-model="scope.tempData.currentValue" value="s"/>游泳</label>
	 *	   </div>
	 * </ab-checkbox>
	 * </pre>
	 */
	@Override
	protected String getColumnCheckBox(IBusinessColumn column) {
		JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
		if (!config.containsKey("options")) {
			throw new BusinessException(String.format("表【%s】CheckBox 字段  【%s】解析失败,options 配置信息不能为空", column.getTable().getKey(), column.getComment()));
		}

		Element checkbox = getElement("ab-checkbox");
		handleVModel(checkbox, column);
		handlePermission(checkbox, column);
		handleValidateRules(checkbox, column);
		Element template = checkbox.appendElement("div").attr("slot-scope", "checkboxScope");

		JSONArray options = config.getJSONArray("options");
		for (int i = 0; i < options.size(); i++) {
			JSONObject option = options.getJSONObject(i);

			Element element = template.appendElement("label").addClass("checkbox-inline");
			Element child = element.appendElement("input").attr("type", "checkbox");
			child.attr("v-model", "checkboxScope.tempData.currentValue");
			child.attr("value", option.getString("key"));
			child.attr("name", String.format("%s-%s-%s", (String) ThreadMapUtil.get("boCode"), column.getTable().getKey(), column.getName()));
			handlePermission(child, column);
			element.appendText(option.getString("txt"));
		}

		return checkbox.toString();
	}

	@Override
	protected String getColumnRadio(IBusinessColumn column) {
		JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
		if (!config.containsKey("options")) {
			throw new BusinessException(String.format("表【%s】Radio 字段  【%s】解析失败,options 配置信息不能为空", column.getTable().getKey(), column.getComment()));
		}

		Element permissionElement = getElement("div");
		JSONArray options = config.getJSONArray("options");
		for (int i = 0; i < options.size(); i++) {
			JSONObject option = options.getJSONObject(i);

			Element label = permissionElement.appendElement("label").addClass("radio-inline");
			Element child = label.appendElement("input").attr("type", "radio");

			handleVModel(child, column);
			child.attr("v-ab-permission", getPermissionPath(column));
			handleValidateRules(child, column);

			child.attr("value", option.getString("key"));
			label.appendText(option.getString("txt"));
		}

		return permissionElement.toString();
	}

	@Override
	protected String getColumnSelect(IBusinessColumn column, Boolean isMultiple) {
		JSONObject config = JSON.parseObject(column.getCtrl().getConfig());
		if (!config.containsKey("options")) {
			throw new BusinessException(String.format("表【%s】Select 字段  【%s】解析失败,options 配置信息不能为空", column.getTable().getKey(), column.getComment()));
		}

		Element permissionElement = getElement("select").addClass("form-control");
		handleVModel(permissionElement, column);
		permissionElement.attr("v-ab-permission", getPermissionPath(column));
		handleValidateRules(permissionElement, column);

		if (isMultiple) {
			permissionElement.attr("multiple", "true");
		}

		Element select = permissionElement.appendElement("option");
		select.attr("value", "");
		select.text("请选择");

		JSONArray options = config.getJSONArray("options");
		for (int i = 0; i < options.size(); i++) {
			JSONObject option = options.getJSONObject(i);

			Element element = permissionElement.appendElement("option");
			element.attr("value", option.getString("key"));
			element.text(option.getString("txt"));
		}

		return permissionElement.toString();
	}
	
	//<ab-upload href="javascript:void(0)" class=" btn btn-primary fa-upload" v-model="data.kjcs.fjsc"></ab-upload>
	protected String getColumnFile(IBusinessColumn column) {
		Element element = getElement("ab-upload").attr("href", "javascript:void(0)").addClass("btn btn-primary fa-upload");
		handleVModel(element, column);
		element.attr(":ab-permission", getPermissionPath(column));
		
		IBusTableRel relation = (IBusTableRel) ThreadMapUtil.get("relation");
		//为了validateRule提示
		element.attr("desc",relation.getTableComment() + "-" + column.getComment());
		return element.toString();
	}

	// id="boCode-tableKey" ab-basic-permission="boCode.table.tableKey" ...
	@Override
	public String getSubAttrs(IBusTableRel rel) {
		StringBuilder sb = new StringBuilder();
		sb.append(" id=" + "\"" + rel.getBusObj().getKey() + "-" + rel.getTableKey() + "\" ");

		// 一对多的三层情况下弹框展示
		if (rel.getType().equals(BusTableRelType.ONE_TO_MANY.getKey()) && !rel.getParent().getType().equals(BusTableRelType.MAIN.getKey())) {
			sb.append(" hide ");
		}

		sb.append(" table-key=\"" + rel.getTableKey() + "\" ");
		return sb.toString();
	}

	@Override
	protected void handlePermission(Element element, IBusinessColumn column) {
		element.attr("v-ab-permission", getPermissionPath(column));
	}

	@Override
	protected void handleValidateRules(Element element, IBusinessColumn column) {
		super.handleValidateRules(element, column);

		element.attr("v-ab-validate", element.attr("ab-validate"));
		element.removeAttr("ab-validate");
	}
	
	@Override
	public String getGeneratorName() {
		return "vueGenerator";
	}
	
	@Override
	public String getScopePath(IBusTableRel relation) {
		if(relation.getType().equals(BusTableRelType.MAIN.getKey())) {
			return "data."+relation.getBusObj().getKey();
		}
		
		StringBuilder sb = new StringBuilder();
		// 一对一是对象名字 
		sb.append(relation.getTableKey());
		// 如果是一对多则添加List
		if(relation.getType().equals(BusTableRelType.ONE_TO_MANY.getKey())){
			sb.append("List");
			//第三层后面均为表单模板，模板会从subTempData中获取中间值。
			if(isThreeChildren(relation)) {
				sb.insert(0, "subTempData."+relation.getParent().getTableKey()+".");
				return sb.toString();
			}
		}
		
		
		getParentPath(relation.getParent(),sb);
		
		return sb.toString();
	}
	
	/**
	 * 权限路径
	 * @param column
	 * @return
	 */
	@Override
	protected String getPermissionPath(IBusinessColumn column) {
		String boCode = (String) ThreadMapUtil.get("boCode");
		IBusTableRel relation = (IBusTableRel) ThreadMapUtil.get("relation");
		boolean isLine = (boolean) ThreadMapUtil.getOrDefault("isLine",false);
		if (!isLine && relation.getType().equals(BusTableRelType.ONE_TO_MANY.getKey())) {
			return "scope.permission." + boCode + "." + column.getTable().getKey() + "." + column.getKey();
		}
		return "permission." + boCode + "." + column.getTable().getKey() + "." + column.getKey();
	}
	
	/**
	 * <pre>
	 * 行内专用
	 * </pre>	
	 * @param column
	 * @param relation
	 * @return
	 */
	public String getLineColumn(IBusinessColumn column,IBusTableRel relation) {
		ThreadMapUtil.put("isLine", true);
		String str = super.getColumn(column, relation);
		ThreadMapUtil.remove("isLine");
		return str;
	}
	
	public String getLineColumn(FormGroup group,FormColumn formColumn) {
		IBusTableRel tableRel = group.getTableRelation();
		
		// 一对一子表 的TableRelation 需要从父表中获取
		if(StringUtil.isNotEmpty(formColumn.getTableKey())&& !formColumn.getTableKey().equals(tableRel.getTableKey())) {
			IBusTableRel table = tableRel.find(formColumn.getTableKey());
			if(table != null) {
				tableRel = table;
			}
		}
		
		if(!formColumn.getTableKey().equals(tableRel.getTableKey())) {
			LOG.error("生成表单可能存在异常！formColumnTableKey{},tableRelTableKey{}",formColumn.getTableKey(),tableRel.getTableKey());
		}
		
	    IBusinessColumn businessColumn = tableRel.getTable().getColumnByKey(formColumn.getKey());
		
	    if(businessColumn == null) {
	    	LOG.error("布局模板查找Column配置失败！字段：{}，表：{}",formColumn.getComment(),formColumn.getTableKey());
	    }
	    
		return this.getLineColumn(businessColumn, tableRel);
	}
	
	public String getScopePath_old(IBusTableRel relation) {
		return super.getScopePath(relation);
	}
}
